package cn.edu.zut.soft.graduate.groupCenter.bo.Impl;

import cn.edu.zut.soft.basic.core.constant.Alternative;
import cn.edu.zut.soft.basic.core.model.dao.Criteria;
import cn.edu.zut.soft.basic.core.model.dao.Example;
import cn.edu.zut.soft.graduate.base.bo.BasicBOImpl;
import cn.edu.zut.soft.graduate.base.dao.BasicDAO;
import cn.edu.zut.soft.graduate.core.constant.InviteStatus;
import cn.edu.zut.soft.graduate.core.constant.config.IKEY;
import cn.edu.zut.soft.graduate.core.model.Impl.Group;
import cn.edu.zut.soft.graduate.core.model.Impl.Identity;
import cn.edu.zut.soft.graduate.core.model.Impl.Invite;
import cn.edu.zut.soft.graduate.core.model.Impl.Message;
import cn.edu.zut.soft.graduate.core.query.InviteQuery;
import cn.edu.zut.soft.graduate.core.vo.LoginVO;
import cn.edu.zut.soft.graduate.groupCenter.bo.GroupBO;
import cn.edu.zut.soft.graduate.groupCenter.bo.InviteBO;
import cn.edu.zut.soft.graduate.groupCenter.dao.InviteDAO;
import cn.edu.zut.soft.graduate.groupCenter.pojo.InviteInfo;
import cn.edu.zut.soft.graduate.massageCenter.bo.MessageBO;
import cn.edu.zut.soft.graduate.massageCenter.generator.Impl.InviteGroupBuilder;
import cn.edu.zut.soft.graduate.massageCenter.pojo.SendMessage;
import cn.edu.zut.soft.graduate.userCenter.bo.IdentityBO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author chuchuang
 * @date 16/11/29
 */
@Service
public class InviteBOImpl extends BasicBOImpl<Invite,InviteQuery> implements InviteBO {

    @Autowired
    private InviteDAO<Invite> inviteDAO;

    @Autowired
    private GroupBO groupBO;

    @Autowired
    private IdentityBO identityBO;

    @Autowired
    private MessageBO messageBO;

    @Autowired
    private InviteGroupBuilder inviteGroupBuilder;

    @Override
    protected BasicDAO<Integer, Invite> getDAO() {
        return inviteDAO;
    }

    @Override
    protected List<Criteria> Query(InviteQuery inviteQuery) {
        Criteria criteria = new Criteria();
        if (inviteQuery.getGroupId() != null){
            criteria.andEqualTo("group_id",inviteQuery.getGroupId());
        }
        if (inviteQuery.getActivesId() != null){
            criteria.andEqualTo("actives_id",inviteQuery.getActivesId());
        }
        if (inviteQuery.getPassivesId() != null){
            criteria.andEqualTo("passives_id",inviteQuery.getPassivesId());
        }
        if (inviteQuery.getStatus() != null){
            criteria.andEqualTo("`status`",inviteQuery.getStatus());
        }else {
            criteria.andIn("`status`",inviteQuery.getInviteStatusList());
        }
        if (inviteQuery.getDel() != null){
            criteria.andEqualTo("del",inviteQuery.getDel());
        }else {
            criteria.andEqualTo("del",IKEY.ZERO);
        }
        if (StringUtils.isNotBlank(inviteQuery.getActivesName())) {
            criteria.andLike("actives_name", inviteQuery.getActivesName() + "%");
        }
        if (StringUtils.isNotBlank(inviteQuery.getPassivesName())){
            criteria.andLike("passives_name",inviteQuery.getPassivesName()+ "%");
        }
        return Collections.singletonList(criteria);
    }

    @Override
    @Transactional
    public Invite inviteOp(InviteInfo inviteInfo, InviteStatus inviteStatus) {
        Assert.notNull(inviteInfo);
        Assert.notNull(inviteStatus);
        Invite invite = null;
        //发出邀请
        if (InviteStatus.ING == inviteStatus){
            //效验小组是否存在
            Group group = groupBO.get(inviteInfo.getGroup().getId());
            Assert.notNull(group,"小组不存在");
            Assert.isTrue(group.getDel() == IKEY.ZERO,"小组已经删除");
            inviteInfo.setGroup(group);
            Identity identity = identityBO.get(inviteInfo.getPassives().getId());
            Assert.notNull(identity,"被邀请人不存在");
            Assert.notNull(identity.getDel() == IKEY.ZERO,"用户被禁用");
            inviteInfo.setPassives(identity);

            invite = new Invite();
            invite.setStatus(inviteStatus);
            invite.setGroupId(inviteInfo.getGroup().getId());
            invite.setActivesId(inviteInfo.getLoginVO().getId());
            invite.setActivesName(inviteInfo.getLoginVO().getName());
            invite.setPassivesId(inviteInfo.getPassives().getId());
            invite.setPassivesName(inviteInfo.getPassives().getName());
            //保存
            this.afterSave(invite,inviteInfo.getLoginVO().getName());
            getDAO().insertSelective(invite);
            SendMessage result = messageBO.AssemblyAndSend(inviteInfo.getLoginVO(), Collections.singletonList(invite.getPassivesId()), inviteGroupBuilder);

        }else if (InviteStatus.YES == inviteStatus || InviteStatus.NO == inviteStatus){
            invite = getDAO().selectByPrimaryKey(inviteInfo.getInvite().getId());
            Assert.notNull(invite,"邀请不存在");
            Assert.isTrue(invite.getDel() == IKEY.ZERO && InviteStatus.ING==invite.getStatus(),"邀请状态不正确");
            inviteInfo.setInvite(invite);
            if (InviteStatus.YES == inviteStatus) {
                Group group = groupBO.get(invite.getGroupId());
                Assert.notNull(group, "小组不存在");
                Assert.isTrue(group.getDel() == IKEY.ZERO, "小组已经删除");
                inviteInfo.setGroup(group);
            }
            //加入小组
            /**
             * 无论同意与否,需要去加入或拒绝小组中发送消息,如果不发送消息则可以修改。主要是为了兼容
             */
            groupBO.joinGroup(inviteInfo.getLoginVO(),inviteInfo.getGroup().getId(), inviteStatus == InviteStatus.YES ? Alternative.YES : Alternative.NO);
            inviteInfo.getInvite().setStatus(inviteStatus);
            this.afterUpdate(inviteInfo.getInvite(),inviteInfo.getLoginVO().getName());
            getDAO().updateByPrimaryKeySelective(invite);

            //如果同意,则拒绝当时其他所有的邀请
            if (InviteStatus.YES == inviteStatus){
                Example example = new Example();
                example.createCriteria()
                        .andEqualTo("passives_id",invite.getPassivesId())
                        .andNotEqualTo("id",invite.getId())
                        .andEqualTo("`status`",InviteStatus.ING)
                        .andEqualTo("del",IKEY.ZERO);
                Invite er = new Invite();
                er.setStatus(InviteStatus.NO);
                this.afterUpdate(invite,inviteInfo.getLoginVO().getName());
                getDAO().updateByExampleSelective(er,example);
            }

        }else if (InviteStatus.INVALID == inviteStatus) {
            invite = getDAO().selectByPrimaryKey(inviteInfo.getInvite().getId());
            Assert.notNull(invite, "邀请不存在");
            Assert.isTrue(invite.getDel() == IKEY.ZERO, "课题已经失效");
            invite.setStatus(inviteStatus);
            this.afterUpdate(invite,inviteInfo.getLoginVO().getName());
            getDAO().updateByPrimaryKeySelective(invite);
        }
        return invite;
    }

    public void deleteByGroupId(LoginVO loginVO, Integer id){
        Example example = new Example();
        example.createCriteria().andEqualTo("group_id",id);
        Invite invite = new Invite();
//        invite.setStatus(InviteStatus.INVALID);
        invite.setDel(-1);
        this.afterUpdate(invite,loginVO.getName());
        getDAO().updateByExampleSelective(invite,example);
    }

}
